<style lang="less">
@import "./editable-table.less";
</style>

<template>
    <div>
        <Table ref="table" :columns="columnsList" :data="thisTableData" :loading="loading" border disabled-hover :highlight-row="highlightRow" @on-current-change="onCurrentChange" @on-row-click="rowClick"></Table>
    </div>
</template>

<script>
const editButton = (vm, h, currentRow, index) => {
  return h(
    "Button",
    {
      props: {
        type: currentRow.editting ? "success" : "primary",
        loading: currentRow.saving
      },
      style: {
        margin: "0 5px"
      },
      on: {
        click: event => {
          if (!currentRow.editting) {
            if (currentRow.edittingCell) {
              for (let name in currentRow.edittingCell) {
                currentRow.edittingCell[name] = false;
                vm.edittingStore[index].edittingCell[name] = false;
              }
            }
            vm.edittingStore[index].editting = true;
            vm.thisTableData = JSON.parse(JSON.stringify(vm.edittingStore));
          } else {
            vm.edittingStore[index].saving = true;
            vm.thisTableData = JSON.parse(JSON.stringify(vm.edittingStore));
            let edittingRow = vm.edittingStore[index];
            edittingRow.editting = false;
            edittingRow.saving = false;
            let oldValue = JSON.parse(JSON.stringify(vm.value));
            vm.thisTableData = JSON.parse(JSON.stringify(vm.edittingStore));
            vm.$emit("input", vm.handleBackdata(vm.thisTableData));
            vm.$emit("on-change", vm.handleBackdata(vm.thisTableData), index);
            setTimeout(() => {
              for (let i = 0; i < vm.edittingStore.length; i++) {
                if (i !== index && vm.edittingStore[i].editting) {
                  vm.value[i].select = oldValue[i].select;
                }
              }
            }, 500);
          }
        }
      }
    },
    currentRow.editting ? "保存" : "编辑"
  );
};
const actionButton = (vm, h, currentRow, index) => {
  return h(
    "Button",
    {
      props: {
        type: "primary"
      },

      style: {
        margin: "0 5px"
      },
      on: {
        click: () => {
          vm.$emit(
            "on-action-click",currentRow,
            index
          );
        }
      }
    },
    "操作"
  );
};
const deleteButton = (vm, h, currentRow, index) => {
  return h(
    "Poptip",
    {
      props: {
        confirm: true,
        title: "您确定要删除这条数据吗?",
        transfer: true
      },
      on: {
        "on-ok": () => {
          vm.$emit("on-delete", vm.handleBackdata(vm.thisTableData), index);
          vm.thisTableData.splice(index, 1);
          vm.$emit("input", vm.handleBackdata(vm.thisTableData));
        }
      }
    },
    [
      h(
        "Button",
        {
          style: {
            margin: "0 5px"
          },
          props: {
            type: "error",
            placement: "top"
          }
        },
        "删除"
      )
    ]
  );
};
const incellEditBtn = (vm, h, param) => {
  if (vm.hoverShow) {
    return h(
      "div",
      {
        class: {
          "show-edit-btn": vm.hoverShow
        }
      },
      [
        h("Button", {
          props: {
            type: "text",
            icon: "edit"
          },
          on: {
            click: event => {
              vm.edittingStore[param.index].edittingCell[
                param.column.key
              ] = true;
              vm.thisTableData = JSON.parse(JSON.stringify(vm.edittingStore));
            }
          }
        })
      ]
    );
  } else {
    return h("Button", {
      props: {
        type: "text",
        icon: "edit"
      },
      on: {
        click: event => {
          vm.edittingStore[param.index].edittingCell[param.column.key] = true;
          vm.thisTableData = JSON.parse(JSON.stringify(vm.edittingStore));
        }
      }
    });
  }
};
const saveIncellEditBtn = (vm, h, param) => {
  return h("Button", {
    props: {
      type: "text",
      icon: "checkmark"
    },
    on: {
      click: event => {
        vm.edittingStore[param.index].edittingCell[param.column.key] = false;
        vm.thisTableData = JSON.parse(JSON.stringify(vm.edittingStore));
        vm.$emit("input", vm.handleBackdata(vm.thisTableData));
        vm.$emit(
          "on-cell-change",
          vm.handleBackdata(vm.thisTableData),
          param.index,
          param.column.key
        );
      }
    }
  });
};
const cellInput = (vm, h, param, item) => {
  return h("Input", {
    props: {
      type: "text",
      value: vm.edittingStore[param.index][item.key]
    },
    on: {
      "on-change"(event) {
        let key = item.key;
        vm.edittingStore[param.index][key] = event.target.value;
      }
    }
  });
};
export default {
  name: "canEditTable",
  props: {
    refs: String,
    columnsList: Array,
    value: Array,
    url: String,
    editIncell: {
      type: Boolean,
      default: false
    },
    hoverShow: {
      type: Boolean,
      default: false
    },
    loading:{
        type: Boolean,
        default: false
    },
    highlightRow: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      columns: [],
      thisTableData: [],
      edittingStore: []
    };
  },
  created() {
    this.init();
  },
  methods: {
    init() {
      let vm = this;
      let editableCell = this.columnsList.filter(item => {
        if (item.editable) {
          if (item.editable === true) {
            return item;
          }
        }
      });
      let cloneData = JSON.parse(JSON.stringify(this.value));
      let res = [];
      res = cloneData.map((item, index) => {
        let isEditting = false;
        if (this.thisTableData[index]) {
          if (this.thisTableData[index].editting) {
            isEditting = true;
          } else {
            for (const cell in this.thisTableData[index].edittingCell) {
              if (this.thisTableData[index].edittingCell[cell] === true) {
                isEditting = true;
              }
            }
          }
        }
        if (isEditting) {
          return this.thisTableData[index];
        } else {
          this.$set(item, "editting", false);
          let edittingCell = {};
          editableCell.forEach(item => {
            edittingCell[item.key] = false;
          });
          this.$set(item, "edittingCell", edittingCell);
          return item;
        }
      });
      this.thisTableData = res;
      this.edittingStore = JSON.parse(JSON.stringify(this.thisTableData));
      this.columnsList.forEach(item => {
        if (item.editable) {
          item.render = (h, param) => {
            let currentRow = this.thisTableData[param.index];
            if (!currentRow.editting) {
              if (this.editIncell) {
                return h(
                  "Row",
                  {
                    props: {
                      type: "flex",
                      align: "middle",
                      justify: "center"
                    }
                  },
                  [
                    h(
                      "Col",
                      {
                        props: {
                          span: "22"
                        }
                      },
                      [
                        !currentRow.edittingCell[param.column.key]
                          ? h("span", currentRow[item.key])
                          : cellInput(this, h, param, item)
                      ]
                    ),
                    h(
                      "Col",
                      {
                        props: {
                          span: "2"
                        }
                      },
                      [
                        currentRow.edittingCell[param.column.key]
                          ? saveIncellEditBtn(this, h, param)
                          : incellEditBtn(this, h, param)
                      ]
                    )
                  ]
                );
              } else {
                return h("span", currentRow[item.key]);
              }
            } else {
              return h("Input", {
                props: {
                  type: "text",
                  value: currentRow[item.key]
                },
                on: {
                  "on-change"(event) {
                    let key = param.column.key;
                    vm.edittingStore[param.index][key] = event.target.value;
                  }
                }
              });
            }
          };
        }
        if (item.handle) {
          item.render = (h, param) => {
            let currentRowData = this.thisTableData[param.index];
            if (item.handle.length === 2) {
              let buttons = [];
              if (item.handle[0] == "edit" && item.handle[1] == "delete") {
                buttons = [
                  editButton(this, h, currentRowData, param.index),
                  deleteButton(this, h, currentRowData, param.index)
                ];
              } else if (
                item.handle[0] == "action" &&
                item.handle[1] == "delete"
              ) {
                buttons = [
                  actionButton(this, h, currentRowData, param.index),
                  deleteButton(this, h, currentRowData, param.index)
                ];
              }
              return h(
                "div",
                {
                  on: {
                    click(event) {
                      event.stopPropagation();
                    }
                  }
                },
                buttons
              );
            } else if (item.handle.length === 1) {
              if (item.handle[0] === "edit") {
                return h("div", [
                  editButton(this, h, currentRowData, param.index)
                ]);
              } else {
                return h("div", [
                  deleteButton(this, h, currentRowData, param.index)
                ]);
              }
            }
          };
        }
        if (item.isImg) {
          item.render = (h, param) => {
            return h("img", {
              attrs: {
                src: this.postUrl.imgPath + param.row.icon_url
              },
              style: {
                width: "40px",
                height: "40px",
                "margin-top": "5px"
              }
            });
          };
        }
        if (item.selectable) {
          item.render = (h, param) => {
            return h(
              "Select",
              {
                props: {
                  multiple: param.row.multiple,
                  // 'label-in-value':true,
                  value: param.row.select
                },
                on: {
                  "on-change": event => {
                    if (!param.row.multiple) {
                      this.edittingStore[param.index].select = event;
                      if (event !== this.value[param.index].select) {
                        this.edittingStore[param.index].editting = true;
                      } else {
                        this.edittingStore[param.index].editting = false;
                      }
                      this.thisTableData = JSON.parse(
                        JSON.stringify(this.edittingStore)
                      );
                    }
                    this.handleSelectChange(event, param.index);
                  }
                }
              },
              [
                param.row.options.map(item => {
                  return h(
                    "Option",
                    {
                      props: {
                        value: item.uuid,
                        key: item.uuid
                      }
                    },
                    item.label
                  );
                })
              ]
            );
          };
        }
      });
    },
    handleBackdata(data) {
      let clonedData = JSON.parse(JSON.stringify(data));
      clonedData.forEach(item => {
        delete item.editting;
        delete item.edittingCell;
        delete item.saving;
      });
      return clonedData;
    },
    onCurrentChange(currentRow, oldCurrentRow) {
      if (this.highlightRow) {
        this.$emit("on-current-change", currentRow, oldCurrentRow);
      }
    },
    rowClick(currentRow, index) {
      this.$emit("on-row-click", currentRow, index);
    },
    handleClearCurrentRow() {
      this.$refs.table.clearCurrentRow();
    },
    handleSelectChange(value, index) {
      this.$emit("on-select-change", value, index);
    }
  },
  watch: {
    'value':{
      deep: true,
      handler:function(data){
        this.init();
      }
    }
  }
};
</script>
